package com.hccl.SMSDetector;

import com.hccl.answeringSystem.HanLPBinaryAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.similarities.ClassicSimilarity;
import org.apache.lucene.store.Directory;

import org.json.JSONObject;
import java.io.IOException;

import java.util.*;
import java.io.*;

/**
 * Created by Zhao on 2016/03/25.
 */
public class SimilarSMSFinder {

    private Analyzer hanalyzer = new HanLPBinaryAnalyzer();
    private Directory directory;
    Map<SMSEntity, String> lastMap = new HashMap<>();
    double maxScore = Double.MIN_VALUE, minScore = Double.MAX_VALUE, globalMaxScore = Double.MIN_VALUE;

    public void setDirectory(Directory directory) {
        this.directory = directory;
    }

    /*==========================输入为json字符串===================================*/
    public JSONObject searching(String jsonstr) {
        try {
            SMSReader smsreader = new SMSFileReader();
            SMSEntity sms;
            List<SMSEntity> smsList = new ArrayList<>();//建索引的所有数据
            List<SMSEntity> smsListHasSimilar = new ArrayList<>();//similar set
            List<SMSEntity> smsList2 = new ArrayList<>();
            List<SMSEntity> smsNoSimilar = new ArrayList<>();//dissimilar set
            int indexID = 0;
            Map<Integer, List<String>> output = new HashMap<>();
            JSONObject json = new JSONObject(jsonstr);
            JSONObject dataObject = json.getJSONObject("data");
            Iterator it = dataObject.keys();
            while (it.hasNext()) {
                String name = (String) it.next();
                Object content = dataObject.get(name);
                if ((sms = smsreader.getNextSMS((String) name, (String) content)) != null) {
                    if (sms.isExclude()) continue;
                    sms.setSmsContent(sms.getSmsContent());
                    sms.setId(indexID);
                    indexID++;
                    smsList.add(sms);
                }
            }
            //smsreader.close();
            System.out.println("待聚类文本数："+smsList.size());

            int i = 0;
            DirectoryReader iReader = DirectoryReader.open(directory);
            IndexSearcher iSearcher = new IndexSearcher(iReader);
            iSearcher.setSimilarity(new ClassicSimilarity());

            //原始Lucene检索
            for (SMSEntity s : smsList) {
                if (s.isExclude()) continue;
                smsListHasSimilar.add(s);

                String str = QueryParser.escape(s.getSmsContent());
                BooleanQuery.setMaxClauseCount(4096);
                QueryParser parser = new QueryParser("content", hanalyzer);
                Query query = parser.parse(str);
                ScoreDoc[] hits = iSearcher.search(query, null, 320000).scoreDocs;
                boolean hasSimilar = false;
                for (ScoreDoc hit : hits) {
                    minScore = minScore > hit.score ? hit.score : minScore;
                    globalMaxScore = globalMaxScore < hit.score ? hit.score : globalMaxScore;
                    // 阈值t1的使用
                    if (hit.score > Double.parseDouble(json.getString("t1"))) {
                        Document hitDoc = iSearcher.doc(hit.doc);
                        Integer id = new Integer(hitDoc.get("id"));
                        smsList.get(id).setDocid(hit.doc);
                        if (!id.equals(s.getId())) {
                            maxScore = maxScore < hit.score ? hit.score : maxScore;
                            hasSimilar = true;
                            if (!smsList.get(id).isExclude()) smsListHasSimilar.add(smsList.get(id));
                            smsList.get(id).setExclude(true);
                        } else
                            continue;
                    } else
                        break;
                }

                if (hasSimilar) {
                    Random random = new Random();
                    int nextint = random.nextInt(smsListHasSimilar.size());
                    smsList2.add(smsListHasSimilar.get(nextint));
                    lastMap.put(smsListHasSimilar.get(nextint), Integer.toString(i) + ".txt");//lastMap中值是第i个相似文件名i.txt，键为i为该文件中任意的一个SMSEntity
                    s.setExclude(true);
                    List<String> list = new ArrayList<>();
                    for (SMSEntity ss : smsListHasSimilar) {
                        list.add(ss.getFilename());
                    }
                    output.put(i, list);
                    smsListHasSimilar.clear();
                    i++;
                } else {
                    smsNoSimilar.add(s);
                    s.setExclude(true);
                }
            }
            System.out.println("第一次聚类得到" + i + "个文件");
            System.out.println("全局最大globalMaxScore：" + globalMaxScore);
            System.out.println("最小minScore：" + minScore);
            iReader.close();
            directory.close();
            return new JSONObject(output);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /*==========================输入为json字符串===================================*/

    public static JSONObject doClustering(String jsonStr) {
        SMSLoader loader = new SMSLoader();
        loader.indexing(jsonStr);
        SimilarSMSFinder finder = new SimilarSMSFinder();
        finder.setDirectory(loader.getDirectory());
        return finder.searching(jsonStr);
    }

//    public static void main(String[] args)  {
//        double start = System.currentTimeMillis();
//
//        File f=new File("data");
//        Map<String,String> m=new HashMap<>();
//        File[] files=f.listFiles();
//        for(File file:files){
//            String encoding = "UTF-8";
//            Long filelength = file.length();
//            byte[] filecontent = new byte[filelength.intValue()];
//            try {
//                FileInputStream in = new FileInputStream(file);
//                in.read(filecontent);
//                in.close();
//            } catch (FileNotFoundException e) {
//                e.printStackTrace();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            try {
//                m.put(file.getName(),new String(filecontent, encoding));
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//        }
//
//        //调用示例:调用doClustering方法,参数为传入的待分类的文件的json数据，返回值为聚类结果json字符串
//        //System.out.println(new JSONObject(m).toString());
//        String res=SimilarSMSFinder.doClustering(new JSONObject(m).toString());
//        //System.out.println(res);
//
//        double end = System.currentTimeMillis();
//        System.out.println("time is : " + (end - start) / 1000 + " s");
//    }
}